package com.heima.wemedia.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.schedule.dto.Task;
import com.heima.model.wemedia.dtos.NewsAuthDto;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.model.wemedia.vo.WmNewsVo;
import com.heima.utils.ProtostuffUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.AutoScanService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.thread.WmUserThreadLocal;
import com.hema.feign.apis.Article.IArticleClient;
import com.hema.feign.apis.Schedule.IScheduleClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
@Slf4j
@Transactional
public class WmNewsServiceImpl  extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private AutoScanService autoScanService;

    @Autowired
    private IScheduleClient scheduleClient;

    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Autowired
    private WmUserMapper wmUserMapper;

    @Autowired
    private IArticleClient iArticleClient;


    @Override
    public PageResponseResult pagelist(WmNewsPageReqDto dto) {
        if (dto==null){
            return new PageResponseResult(0,0,0);
        }
        Short status = dto.getStatus();
        Date beginPubDate = dto.getBeginPubDate();
        Date endPubDate = dto.getEndPubDate();
        Integer channelId = dto.getChannelId();
        String keyword = dto.getKeyword();
        //构建查询条件
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(status!=null,WmNews::getStatus,status);
        wrapper.between(beginPubDate!=null&&endPubDate!=null,WmNews::getPublishTime,beginPubDate,endPubDate);
        wrapper.like(StringUtils.isNotEmpty(keyword),WmNews::getTitle,keyword);
        wrapper.eq(channelId!=null,WmNews::getChannelId,channelId);
        wrapper.orderByDesc(WmNews::getCreatedTime);
        wrapper.eq(WmNews::getUserId, WmUserThreadLocal.get().getId());
        //构建分页条件
        Page<WmNews> page = new Page<>(dto.getPage(),dto.getSize());
        Page<WmNews> wmNewsPage = wmNewsMapper.selectPage(page, wrapper);
        //组装结果
        Long total = wmNewsPage.getTotal();
        PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(),dto.getSize(),total.intValue());
        pageResponseResult.setData(wmNewsPage.getRecords());
        return pageResponseResult;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ResponseResult submit(WmNewsDto dto) {
        //1.提取新闻内容
        WmNews wmNews = submitPull(dto);
        if (wmNews==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //2.保存wmnews
        int i = wmNewsMapper.insert(wmNews);
        if (i<1){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //3.判断是否是草稿
        Short status = dto.getStatus();
        if (status==0){
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }
        //4.提取新闻图片
        List<String> contentImages = getContentImages(dto.getContent());
        //判断是否是自动模式
        List<String> images = dto.getImages();
        Short type = dto.getType();
        List<String> coverImages = getCoverImages(type, images, contentImages);
        //5.添加内容图添加封面图
        Boolean aBoolean = addMaterial(wmNews.getId(), contentImages, 0);
        if (!aBoolean){
            throw new RuntimeException("素材添加失败");
        }
        Boolean aBoolean2 = addMaterial(wmNews.getId(), coverImages, 1);
        if (!aBoolean2){
            throw new RuntimeException("素材添加失败");
        }
        //添加任务
        addToTask(wmNews.getPublishTime().getTime(),wmNews.getId());

        //添加审核流程
//        try {
//            autoScanService.antoScanWmNews(wmNews.getId().longValue());
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult downOrUp(WmNewsDto wmNewsDto) {
        WmNews wmNews = wmNewsMapper.selectById(wmNewsDto.getId());
        if (wmNews==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        Short status = wmNews.getStatus();
        if (status!=9){
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        wmNews.setEnable(wmNewsDto.getEnable());
        wmNewsMapper.updateById(wmNews);
        Map<String, Object> map = new HashMap<>();
        map.put("articleId",wmNews.getArticleId());
        map.put("enable",wmNews.getEnable());
        kafkaTemplate.send("down.Or.Up",JSON.toJSONString(map));

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult findList(NewsAuthDto dto) {
        // 1.参数检查
        dto.checkParam();

        // 2.记录当前页
        int currentPage = dto.getPage();

        // 3.分页查询+count查询
        dto.setPage((dto.getPage() - 1) * dto.getSize());
        List<WmNewsVo> listAndPage = wmNewsMapper.findListAndPage(dto);
        Integer count = wmNewsMapper.findListCount(dto);

        // 4.结果返回
        ResponseResult responseResult = new PageResponseResult(currentPage, dto.getSize(), count);
        responseResult.setData(listAndPage);
        return responseResult;
    }

    @Override
    public ResponseResult findWmNewsVo(Integer id) {
        if (id==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews wmNews = wmNewsMapper.selectById(id);
        Integer userId = wmNews.getUserId();
        WmUser wmUser = wmUserMapper.selectById(userId);
        WmNewsVo wmNewsVo = new WmNewsVo();
        wmNewsVo.setAuthorName(wmUser.getName());
        BeanUtils.copyProperties(wmNewsVo,wmNews);

        return ResponseResult.okResult(wmNewsVo);
    }

    @Override
    public ResponseResult auth(NewsAuthDto dto, Integer type) {
        if (dto==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Integer id = dto.getId();
        String msg = dto.getMsg();
        WmNews wmNews = wmNewsMapper.selectById(id);
        int status = type == 1 ? 9 : 2;
        wmNews.setStatus((short) status);
        wmNews.setReason(type==1?"通过":msg);
        int updateReult= wmNewsMapper.updateById(wmNews);
        if (updateReult>1){
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR, "新闻审核失败");
        }
        if (type == 1) {
            ArticleDto articleDto = autoScanService.wmNews2ArticleDto(wmNews);
            ResponseResult responseResult = iArticleClient.saveArticle(articleDto);
            if (responseResult == null || responseResult.getCode() != 200) {
                throw new RuntimeException("文章保存失败");
            }
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    //添加任务流程
    public Boolean addToTask(Long executeTime,Integer newsId){
        Task task=new Task();
        task.setExecuteTime(executeTime);
        WmNews wmNews = new WmNews();
        wmNews.setId(newsId);
        byte[] serialize = ProtostuffUtil.serialize(wmNews);
        task.setParameters(serialize);
        ResponseResult responseResult = scheduleClient.addTask(task);
        if (responseResult!=null&&responseResult.getCode()==200){
            return true;
        }
        return false;
    }


    @Transactional(rollbackFor = RuntimeException.class)
    //添加内容图添加封面图
    public Boolean addMaterial(Integer newsId,List<String> imagesList,Integer type){
        if (CollectionUtils.isEmpty(imagesList)) {
            return true;
        }
        for (String item : imagesList) {
            if (StringUtils.isEmpty(item)) {
                continue;
            }
            WmMaterial wmMaterial=new WmMaterial();
            wmMaterial.setUrl(item);
            wmMaterial.setIsCollection((short) 0);
            wmMaterial.setType((short) 0);
            wmMaterial.setCreatedTime(new Date());
            wmMaterial.setUserId(WmUserThreadLocal.get().getId());
            int i = wmMaterialMapper.insert(wmMaterial);
            if (i<1){
                throw new RuntimeException("素材添加失败");
            }
            WmNewsMaterial wmNewsMaterial=new WmNewsMaterial();
            wmNewsMaterial.setMaterialId(wmMaterial.getId());
            wmNewsMaterial.setNewsId(newsId);
            wmNewsMaterial.setOrd((short) 1);
            wmNewsMaterial.setType(type.shortValue());
            int i1= wmNewsMaterialMapper.insert(wmNewsMaterial);
            if (i1<1){
                throw new RuntimeException("素材添加失败");
            }
        }
        return true;

    }

    //提取封面图
    public List<String> getCoverImages(Short type,List<String> images,List<String> contentImages){
        if (type==-1){
            int size = contentImages.size();
            if (size>=3){
                contentImages.subList(0,3);
            }else if (size==2){
                contentImages.subList(0,1);
            }else if (size==1){
                ArrayList<String> list = new ArrayList<>();
                list.add(contentImages.get(0));
                return list;
            }else {
                return new ArrayList<>();
            }
        }
        return images;
    }

    //提取内容图片
    public List<String> getContentImages(String content) {
        List<Map> maps = JSON.parseArray(content, Map.class);
        ArrayList<String> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(maps)) {
            return new ArrayList<>();
        }
        for (Map map : maps) {
            if (CollectionUtils.isEmpty(map)) {
                continue;
            }
            Object type = map.get("type");
            if ("image".equals(type)){
                String value = (String) map.get("value");
                list.add(value);

            }
        }
        return list;
    }

    //提取新闻内容方法
    private WmNews submitPull(WmNewsDto dto){
        WmNews wmNews=new WmNews();
        BeanUtils.copyProperties(dto,wmNews);
        Short type = dto.getType();
        if (type==-1){
            wmNews.setType(null);
        }
        wmNews.setCreatedTime(new Date());
        List<String> images = dto.getImages();
        String image = StringUtils.join(images, ",");
        wmNews.setImages(image);
        Integer id = WmUserThreadLocal.get().getId();
        wmNews.setUserId(id);
        wmNews.setEnable((short) 1);
        return wmNews;
    }
}
